/**
 * This class is the implementation base for CORBA implementation.
 * 
 * 
 * @author	Jerome DANIEL.
 */

package org.omg.CORBA;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

abstract public class ORB {
	//
	// This is the ORB implementation used when nothing else is specified.
	// Whoever provides this class customizes this string to
	// point at their ORB implementation.
	//
	private static final String ORBClassKey = "org.omg.CORBA.ORBClass";
	private static final String ORBSingletonClassKey = "org.omg.CORBA.ORBSingletonClass";

	//
	// The last resort fallback ORB implementation classes in case
	// no ORB implementation class is dynamically configured through
	// properties or applet parameters. Change these values to
	// vendor-specific class names.
	//
	private static final String defaultORB = "org.huihoo.orbas.orb.ORB";
	private static final String defaultORBSingleton = "org.huihoo.orbas.orb.ORBSingleton";

	/**
	 * A reference to the singleton
	 */
	private static org.omg.CORBA.ORB _singleton;

	private static String getSystemProperty(final String name) {
		try {
			return System.getProperty(name);
		} catch (SecurityException ex) {
			return null;
		}
	}

	/**
	 * Properties from the orb.properties file
	 */
	private static Properties fileProps = null;

	private static String getPropertyFromFile(final String name) {
		if (fileProps == null) {
			fileProps = new Properties();
			try {
				// Check if orb.properties exists
				String javaHome = System.getProperty("java.home");
				File propFile = new File(javaHome + File.separator + "lib"
						+ File.separator + "orb.properties");
				if (!propFile.exists())
					return null;

				// Load properties from orb.properties
				FileInputStream fis = new FileInputStream(propFile);
				try {
					fileProps.load(fis);
				} finally {
					fis.close();
				}
			} catch (Exception ex) {
				return null;
			}
		}

		return fileProps.getProperty(name);
	}

	public void destroy() {

	}

	/**
	 * Initialize the ORB singleton
	 */
	public static ORB init() {
		if (_singleton == null) {
			String className = getSystemProperty(ORBClassKey);
			if (className == null)
				className = getPropertyFromFile(ORBClassKey);
			if (className == null)
				className = defaultORB;

			try {
				_singleton = (ORB) Class.forName(className).newInstance();
			} catch (Exception ex) {
				throw new INITIALIZE("can't instantiate ORB implementation "
						+ className);
			}
		}
		return _singleton;
	}

	private static ORB initOrb() {
		String className = getSystemProperty(ORBClassKey);
		if (className == null)
			className = getPropertyFromFile(ORBClassKey);
		if (className == null)
			className = defaultORB;

		try {
			return (ORB) Class.forName(className).newInstance();
		} catch (Exception ex) {
			throw new INITIALIZE("can't instantiate ORB implementation "
					+ className);
		}
	}

	/**
	 * Create a new ORB
	 */
	public static ORB init(String[] args, java.util.Properties props) {
		org.omg.CORBA.ORB orb = initOrb();

		orb.set_parameters(args, props);

		return orb;
	}

	abstract protected void set_parameters(String[] args,
			java.util.Properties props);

	public void connect(org.omg.CORBA.Object obj) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public void disconnect(org.omg.CORBA.Object obj) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	abstract public String[] list_initial_services();

	abstract public org.omg.CORBA.Object resolve_initial_references(
			String object_name) throws org.omg.CORBA.ORBPackage.InvalidName;

	abstract public String object_to_string(org.omg.CORBA.Object obj);

	abstract public org.omg.CORBA.Object string_to_object(String str);

	abstract public NVList create_list(int count);

	public NVList create_operation_list(org.omg.CORBA.Object oper) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	abstract public NamedValue create_named_value(String s, Any any, int flags);

	abstract public ExceptionList create_exception_list();

	abstract public ContextList create_context_list();

	abstract public Context get_default_context();

	abstract public Environment create_environment();

	abstract public org.omg.CORBA.portable.OutputStream create_output_stream();

	abstract public void send_multiple_requests_oneway(Request[] req);

	abstract public void send_multiple_requests_deferred(Request[] req);

	abstract public boolean poll_next_response();

	abstract public Request get_next_response() throws WrongTransaction;

	abstract public TypeCode get_primitive_tc(TCKind tcKind);

	abstract public TypeCode create_struct_tc(String id, String name,
			StructMember[] members);

	abstract public TypeCode create_union_tc(String id, String name,
			TypeCode discriminator_type, UnionMember[] members);

	abstract public TypeCode create_enum_tc(String id, String name,
			String[] members);

	abstract public TypeCode create_alias_tc(String id, String name,
			TypeCode original_type);

	abstract public TypeCode create_exception_tc(String id, String name,
			StructMember[] members);

	abstract public TypeCode create_interface_tc(String id, String name);

	abstract public TypeCode create_string_tc(int bound);

	abstract public TypeCode create_wstring_tc(int bound);

	abstract public TypeCode create_sequence_tc(int bound, TypeCode element_type);

	abstract public TypeCode create_recursive_sequence_tc(int bound, int offset);

	abstract public TypeCode create_array_tc(int length, TypeCode element_type);

	public org.omg.CORBA.TypeCode create_native_tc(String id, String name) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.TypeCode create_abstract_interface_tc(String id,
			String name) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.TypeCode create_fixed_tc(short digits, short scale) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.TypeCode create_value_tc(String id, String name,
			short type_modifier, TypeCode concrete_base, ValueMember[] members) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.TypeCode create_recursive_tc(String id) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.TypeCode create_value_box_tc(String id, String name,
			TypeCode boxed_type) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	abstract public Any create_any();

	public org.omg.CORBA.Current get_current() {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public void run() {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public void shutdown(boolean wait_for_completion) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public boolean work_pending() {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public void perform_work() {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public boolean get_service_information(short service_type,
			ServiceInformationHolder service_info) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.Policy create_policy(int type, org.omg.CORBA.Any val)
			throws org.omg.CORBA.PolicyError {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

}
